<template>
    <div v-if="enable" style="padding:5px">
        <el-button type="primary" style="margin:5px 5px 5px 0px"  size="small" @click="add">添加</el-button>
        <el-button type="primary" style="margin:5px"  size="small" @click="showListenerSelectDialog">选择</el-button>
        <el-dialog title="添加任务监听器" v-model="visible" append-to-body draggable>
          <el-form  ref="inputForm" label-width="120px" :model="inputForm">
            <el-form-item label="事件类型" prop="event"> 
             <el-select v-model="inputForm.event" placeholder="请选择">
                <el-option
                  v-for="item in [{
                    value: 'create',
                    label: 'create'
                  },{
                    value: 'assignment',
                    label: 'assignment'
                  },{
                    value: 'complete',
                    label: 'complete'
                  },{
                    value: 'delete',
                    label: 'delete'
                  }]"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="监听类型" prop="type">
              <el-select v-model="inputForm.type" placeholder="请选择">
                 <el-option
                  v-for="item in [{
                    value: 'JavaClass',
                    label: '类'
                  },{
                    value: 'Expression',
                    label: '表达式'
                  },{
                    value: 'DelegateExpression',
                    label: '委托表达式'
                  }]"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item v-if="inputForm.type === 'JavaClass'" label="类" prop="class" :rules="[
                {required: true, message:'类不能为空', trigger:'blur'}
                 ]">
              <el-input v-model="inputForm.class" ></el-input>
            </el-form-item>
             <el-form-item v-if="inputForm.type === 'Expression'" label="表达式" prop="expression" :rules="[
                {required: true, message:'表达式不能为空', trigger:'blur'}
                 ]">
              <el-input v-model="inputForm.expression" ></el-input>
            </el-form-item>
             <el-form-item v-if="inputForm.type === 'DelegateExpression'" label="委托表达式" prop="delegateExpression" :rules="[
                {required: true, message:'委托表达式不能为空', trigger:'blur'}
                 ]">
              <el-input v-model="inputForm.delegateExpression" ></el-input>
            </el-form-item>
          </el-form>
          <template #footer>
            <span class="dialog-footer">
                  <el-button  @click="visible = false">取 消</el-button>
                  <el-button  type="primary" @click="save">确定</el-button>
            </span>
          </template>
        </el-dialog>
        <el-table
          :data="tableData"
          size="small"
          border>
          <el-table-column
            prop="event"
            label="事件">
          </el-table-column>
          <el-table-column
            prop="type"
            label="类型">
            <template #default="scope">
              {{category[scope.row.type]}}
            </template>
          </el-table-column>
          <el-table-column
            prop="impl"
             :show-overflow-tooltip="true"
            label="实现">
            <template #default="scope">
              {{scope.row.class || scope.row.expression || scope.row.delegateExpression}}
            </template>
          </el-table-column>
           <el-table-column
            fixed="right"
            header-align="center"
            align="center"
            width="100"
            label="操作">
            <template #default="scope">
              <el-button type="primary" text  size="small"   @click="edit(scope.row)">
                修改
              </el-button>
              <el-button  type="danger" text  size="small"   @click="del(scope.row)">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <ListenerSelect ref="listenerSelect" @selectListener="selectListener"></ListenerSelect>
    </div>
</template>
<script>
// let nameEntryFactory = import('./implementation/Name')
// let createCategoryValue = import('jp-bpmn-js-properties-panel/lib/helper/CategoryHelper').createCategoryValue
// import elementHelper from 'jp-bpmn-js-properties-panel/lib/helper/ElementHelper'
import pick from 'lodash.pick'
import ListenerSelect from './ListenerSelect.vue'
import { is } from 'jeeplus-bpmn/lib/util/ModelUtil'
import { getBusinessObject } from 'jeeplus-bpmn/lib/util/ModelUtil'
// let translate = import('diagram-js/lib/i18n/translate').default
// let extensionElementsEntry = import('./ExtensionElements')
// import elementHelper from 'jp-bpmn-js-properties-panel/lib/helper/ElementHelper'
import elementHelper from 'jp-bpmn-js-properties-panel/lib/helper/ElementHelper'
// let ImplementationTypeHelper = import('jp-bpmn-js-properties-panel/lib/helper/ImplementationTypeHelper')

// var CAMUNDA_EXECUTION_LISTENER_ELEMENT = 'flowable:ExecutionListener'
// var CAMUNDA_TASK_LISTENER_ELEMENT = 'flowable:TaskListener'
export default {
  props: {
    element: {
      type: Object,
      default: undefined
    },
    bpmnModeler: {
      type: Object,
      default: undefined
    }
  },
  data () {
    return {
      visible: false,
      tableData: [],
      impl: '',
      oldRow: null,
      category: {
        'JavaClass': '类',
        'Expression': '表达式',
        'DelegateExpression': '委托表达式'
      },
      inputForm: {
        type: 'JavaClass',
        class: '',
        delegateExpression: '',
        event: 'start',
        expression: ''
      }
    }
  },
  methods: {
    add () {
      this.visible = true
      this.oldRow = null
      this.$nextTick(() => {
        this.$refs['inputForm'].resetFields()
      })
    },
    edit (row) {
      this.visible = true
      this.oldRow = row
      this.inputForm = JSON.parse(JSON.stringify(row))
    },
    save () {
      this.$refs['inputForm'].validate((valid) => {
        if (valid) {
          if (this.inputForm.type === 'JavaClass') {
            this.inputForm.expression = ''
            this.inputForm.delegateExpression = ''
          }
          if (this.inputForm.type === 'Expression') {
            this.inputForm.class = ''
            this.inputForm.delegateExpression = ''
          }
          if (this.inputForm.type === 'DelegateExpression') {
            this.inputForm.class = ''
            this.inputForm.expression = ''
          }
          if (this.oldRow === null) {
            this.tableData.push(JSON.parse(JSON.stringify(this.inputForm)))
          } else {
            this.tableData.forEach((item, index) => {
              if (item === this.oldRow) {
                this.tableData.splice(index, 1, this.inputForm)
              }
            })
          }
          this.visible = false
        }
      })
    },
    del (row) {
      this.tableData.forEach((item, index) => {
        if (item === row) {
          this.tableData.splice(index, 1)
        }
      })
    },
    updateElements (tableDatas) {
      let element = this.element
      let bo = getBusinessObject(element)
      let parent = this.getExtensionElements(element)

      if (!parent && typeof this.createExtensionElements === 'function') {
        parent = this.createExtensionElements(element, bo)
      }
      let objList = []
      tableDatas.forEach((row) => {
        let obj = {}
        if (row.class) {
          obj = pick(row, 'event', 'class')
        } else if (row.delegateExpression) {
          obj = pick(row, 'event', 'delegateExpression')
        } else if (row.expression) {
          obj = pick(row, 'event', 'expression')
        }
        var listener = elementHelper.createElement('flowable:TaskListener', obj, parent, this.bpmnModeler.get('bpmnFactory'))
        objList.push(listener)
      })
      let old = []
      if (this.element.businessObject.extensionElements) {
        this.element.businessObject.extensionElements.values.forEach((value) => {
          if (is(value, 'flowable:TaskListener')) {
            old.push(value)
          }
        })
      }
      this.bpmnModeler.get('commandStack').execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: parent,
        propertyName: 'values',
        objectsToRemove: old
      })

      this.bpmnModeler.get('commandStack').execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: parent,
        propertyName: 'values',
        objectsToAdd: objList
      })
    },
    getExtensionElements (element) {
      let bo = getBusinessObject(element)
      return bo.extensionElements
    },
    createExtensionElements: function (element, bo) {
      var extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, this.bpmnModeler.get('bpmnFactory'))
      bo.extensionElements = extensionElements
      return extensionElements
    },
    isExtensionElements (element) {
      return is(element, 'bpmn:ExtensionElements')
    },
    showListenerSelectDialog () {
      this.$refs.listenerSelect.init('2')
    },
    selectListener (list) {
      list.forEach((listener) => {
        if (listener.valueType === '1') {
          listener.type = 'JavaClass'
          listener.class = listener.value
        }
        if (listener.valueType === '2') {
          listener.type = 'Expression'
          listener.expression = listener.value
        }
        if (listener.valueType === '3') {
          listener.type = 'DelegateExpression'
          listener.delegateExpression = listener.value
        }
        this.tableData.push(JSON.parse(JSON.stringify(listener)))
      })
    }
  },
  computed: {
    enable () {
      return true
    }
  },
  components: {
    ListenerSelect
  },
  watch: {
    tableData: {
      handler (newVal) {
        if (this.element) {
          this.updateElements(newVal)
        }
      },
      deep: true
    },
    'element': {
      handler (newVal) {
        this.tableData = []
        if (this.element.businessObject.extensionElements) {
          this.element.businessObject.extensionElements.values.forEach((value) => {
            if (is(value, 'flowable:TaskListener')) {
              value = pick(value, 'class', 'delegateExpression', 'event', 'expression')
              if (value.class) {
                value.type = 'JavaClass'
                value.impl = value.class
              }
              if (value.expression) {
                value.type = 'Expression'
                value.impl = value.expression
              }
              if (value.delegateExpression) {
                value.type = 'DelegateExpression'
                value.impl = value.delegateExpression
              }
              this.tableData.push(JSON.parse(JSON.stringify(value)))
            }
          })
        }
      },
      immediate: true,
      deep: false
    }
  }
}
</script>
